package com.yangzheandroid.rxmvp.http.download;

import android.util.Log;

import com.yangzheandroid.retrofitutils.rx.RxBus;
import com.yangzheandroid.rxmvp.utils.IOUtils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import rx.Subscription;
import rx.functions.Action1;

/**
 * 文件下载Callback
 */
public abstract class DownloadCallback implements Callback<ResponseBody> {
    public static final String TAG = DownloadCallback.class.getSimpleName();
    /**
     * 目标文件存储的文件夹路径
     */
    private String destFileDir;
    /**
     * 目标文件存储的文件名
     */
    private String destFileName;

    private Subscription mSubscription;

    public DownloadCallback(String destFileDir, String destFileName) {
        this.destFileDir = destFileDir;
        this.destFileName = destFileName;

        // 订阅下载进度
        mSubscription = RxBus.getDefault()
                .doSubscribe(ProgressBean.class,
                        new Action1<ProgressBean>() {
                            @Override
                            public void call(ProgressBean bean) {
                                onProgress(bean);
                            }
                        },
                        new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                Log.e(TAG, "网络错误:  " + throwable.toString());
                            }
                        });
    }

    /**
     * 成功后回调
     */
    public abstract void onSuccess(File file);

    /**
     * 下载过程回调
     */
    public abstract void onProgress(ProgressBean bean);

    /**
     * 请求成功后保存文件
     */
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        if (response.isSuccessful()) {
            try {
                saveFile(response);
            } catch (Exception e) {
                this.onFailure(call, e);
            }
        } else {
            this.onFailure(call, new Exception(response.code() + " " + response.message()));
        }
    }

    /**
     * 通过IO流写入文件
     */
    public void saveFile(Response<ResponseBody> response) throws Exception {
        BufferedInputStream bis = null;
        FileOutputStream out = null;
        try {
            File dir = new File(destFileDir);
            if (!dir.exists()) {// 如果文件不存在新建一个
                dir.mkdirs();
            }
            File file = new File(dir, destFileName);
            out = new FileOutputStream(file);

            bis = new BufferedInputStream(response.body().byteStream());

            byte[] buf = new byte[2048];
            int len;
            while ((len = bis.read(buf)) != -1) {
                out.write(buf, 0, len);
                out.flush();
            }

            // 回调成功的接口
            onSuccess(file);

        } finally {
            unSubscribe();// 取消订阅

            IOUtils.close(bis);
            IOUtils.close(out);
        }
    }

    /**
     * 取消订阅，防止内存泄漏
     */
    private void unSubscribe() {
        if (!mSubscription.isUnsubscribed()) {
            mSubscription.unsubscribe();
        }
    }
}
